﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Text;
using Amib.Threading;
using System.Net;
using System.IO;
using System.Xml;
using System.Xml.Linq;
using HPPUtil;
using HPPNet;
using System.Threading;
using HPPUtil.Helpers;

namespace HPPClientLibrary.DownLoad
{
    public class DownloadJob
    {
        #region Fields

        private JobInfo _jobInfo;//Download对应的JobInfo

        /// <summary>
        /// 进行调试前的Peer信息列表(ip+port,peerInfo)
        /// </summary>
        private Dictionary<string, PeerInfo> _beforeDispatchPeerList;

        /// <summary>
        /// 等待下载队列  (blockID,clientIP)
        /// </summary>
        private Dictionary<int, string> _waitingQueue;

        /// <summary>
        /// 正在下载的队列(IP+port ,块数)
        /// </summary>
        private Dictionary<string, int> _downloadingQueue;

        /// <summary>
        /// 已经过时的 IP(IP+Port)
        /// </summary>
        private List<string> _disableIPList;

        private int _downloadSpeed;//下载速度（单位：Byte/s）
        private SmartThreadPool _otherWorkThreadPool;//处理非DownloadPeer的线程池
        private SmartThreadPool _downloadThreadPool;//处理DownloadPeer的线程池
        private object _syncRoot = new object();
        private object _jobThreadCountSync = new object();//
        private object _bufferCurrentCountSync = new object();
        private object _flushToDiskSync = new object();
        private object _dispatchSync = new object();
        private object _beforeDispatchListSync = new object();
        private int _bufferCurrentCount;//当前buffer的数量

        /// <summary>
        /// 每个任务可用的buffer 总数量，当到达这个数时，一次性写入磁盘
        /// </summary>
        private int _bufferAmount;

        /// <summary>
        /// 当前已经开启的下载线程数
        /// </summary>
        private int _jobThreadCount;

        /// <summary>
        /// IP对应的连接失败次数
        /// </summary>
        private Dictionary<string, int> _ipDisableCount = new Dictionary<string, int>();

        private object _ipDisableCountSync = new object();
        private List<int> _dowmloadingBlocks;//正在下载的块号

        /// <summary>
        /// 是否现在进行调度的标志，如果正在进行调度，则不新开线程下载（此时等待下载队列正在调度）
        /// </summary>
        private bool _isDispatchingFlag = false;

        /// <summary>
        /// 判断是否是从还没分配下载资源（线程等）的暂停状态中继续下载的标志
        /// </summary>
        private bool _isResumeFromDisk = true;

        private long _timeStamp;//竞争调度的最新时间戳
        public delegate void EventHandler(object sender, DownLoadEventArgs e);
        public event EventHandler JobStatusChanged;//Download状态改变发出的事件


        #endregion

        /// <summary>
        /// 构造函数，初始化JobInfo
        /// </summary>
        /// <param name="info"></param>
        public DownloadJob(JobInfo info)
        {
            this.JobInfo = info;
            this._otherWorkThreadPool = JobInfo.Manager.OtherWorkThreadPool;
            _downloadThreadPool = JobInfo.Manager.DownloadThreadPool;
            _bufferAmount = _jobInfo.Manager.Client.Config.BufferSizePerJob / BasicSetting.BlockSize;
            _bufferCurrentCount = 0;
            _downloadingQueue = new Dictionary<string, int>();
            _dowmloadingBlocks = new List<int>();
        }

        public int DownloadSpeed
        {
            get { return _downloadSpeed; }
            protected set { _downloadSpeed = value; }
        }

        public JobInfo JobInfo
        {
            get { return _jobInfo; }
            private set { _jobInfo = value; }
        }

        /// <summary>
        /// 向中央服务器获取拥有此hash的Peer列表
        /// </summary>
        /// <param name="serverIP">中央服务器的IP</param>
        /// <returns></returns>
        public void GetPeerList(IPEndPoint serverIP)
        {
            HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create("http://" + serverIP.ToString() + "/" + JobInfo.FileName + "|" + JobInfo.Hash + "/");
            httpWebRequest.Method = "GET";
            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            string responseString;
            switch (httpWebResponse.StatusCode)
            {
                case HttpStatusCode.NotFound:
                case HttpStatusCode.Forbidden:

                    break;
                case HttpStatusCode.OK:
                    StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.UTF8);// change encoding from default to UTF8, since the server implemented by us use UTF8
                    responseString = streamReader.ReadToEnd().Trim();
                    httpWebResponse.Close();
                    XDocument doc;
                    try
                    {
                        doc = XDocument.Parse(responseString);
                    }
                    catch (Exception ex)
                    {
                        return;

                    }
                    if (doc.Descendants("User").Count() == 0)
                    {
                        return;
                    }
                    var users = from u in doc.Descendants("User")
                                select new { ip = u.Attribute("IP").Value, port = u.Attribute("Port").Value };
                    if (JobInfo.LocalFileBlocks == null || JobInfo.FileLen == 0)
                    {

                        try
                        {
                            JobInfo.FileLen = long.Parse(doc.Root.Element("FileSize").Attribute("Size").Value);
                            JobInfo.BlockAmount = Convert.ToInt32(doc.Root.Element("Blocks").Attribute("Number").Value);
                            JobInfo.LastBlockLen =
                                Convert.ToInt32(doc.Root.Element("LastBlock").Attribute("Size").Value);
                            if (JobInfo.LocalFileBlocks == null)
                            {
                                BitArray bitArray = new BitArray(JobInfo.BlockAmount);
                                bitArray.SetAllPosFalse();
                                JobInfo.LocalFileBlocks = bitArray;
                            }

                        }
                        catch (Exception ex)
                        {
                            CommonLogger.Logger.Warn("GetPeerList() 从xml value转为数字发生错误", ex);
                            return;
                        }
                    }
                    lock (_beforeDispatchListSync)
                    {
                        if (_beforeDispatchPeerList == null)
                        {
                            _beforeDispatchPeerList = new Dictionary<string, PeerInfo>();
                        }
                        _beforeDispatchPeerList.Clear();//清空列表                        
                    }

                    _timeStamp = DateTime.Now.Ticks;
                    foreach (var user in users)
                    {
                        _otherWorkThreadPool.QueueWorkItem(new Action<string, string, IPEndPoint>(GetPeerInfo), JobInfo.Hash, JobInfo.FileName, new IPEndPoint(IPAddress.Parse(user.ip), Convert.ToInt32(user.port)));
                    }
                    break;
                default:
                    break;
            }

        }


        /// <summary>
        /// 获取客户端的文件分块信息，在调用完这个函数后应该将PeerInfo放到_beforeDispatchPeerList中
        /// </summary>
        /// <param name="hash">要下载文件的hash值</param>
        /// <param name="ipEndPoint">一个客户端的IP地址(地址+端口)</param>
        public void GetPeerInfo(string hash, string fileName, IPEndPoint ipEndPoint)
        {

            if (_disableIPList != null && _disableIPList.Contains(ipEndPoint.ToString()))//如果IP地址在过时IP列表中,则返回
            {
                return;
            }
            string responseString;
            HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create("http://" + ipEndPoint.ToString() + "/" + fileName + "|" + hash);
            httpWebRequest.Method = "GET";
            httpWebRequest.KeepAlive = true;
            HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
            StreamReader streamReader = new StreamReader(httpWebResponse.GetResponseStream(), Encoding.UTF8);

            responseString = streamReader.ReadToEnd().Trim();
            XDocument doc;
            BitArray hasBitArray;
            try
            {
                doc = XDocument.Parse(responseString);
            }
            catch (Exception ex)
            {
                return;
            }
            if (doc.Descendants("HasBlocks").Count() == 0)
            {
                return;
            }
            if (doc.Root.Element("HasBlocks") == null)
            {
                CommonLogger.ThreadLogger.Error("GetPeerInfo 里获取 HasBlocks节点出现空引用！");
            }

            hasBitArray = BitArray.GetFromHexString(doc.Root.Element("HasBlocks").Attribute("Blocks").Value, JobInfo.BlockAmount);

            PeerInfo peer = new PeerInfo();
            peer.IPEndPoint = ipEndPoint;
            peer.Blocks = hasBitArray;
            lock (_beforeDispatchListSync)
            {
                if (_beforeDispatchPeerList == null)
                {
                    _beforeDispatchPeerList = new Dictionary<string, PeerInfo>();
                }
                _beforeDispatchPeerList[ipEndPoint.ToString()] = peer;
            }

            DispatchPeers();//进行调度
        }


        /// <summary>
        /// 调度下载文件分块, 直接放入等待下载队列里
        /// </summary>
        public void DispatchPeers()
        {
            long timeString;
            timeString = _timeStamp = DateTime.Now.Ticks;
            lock (_dispatchSync)
            {
                try
                {
                    if (timeString < _timeStamp)
                    {
                        return;
                    }
                    CommonLogger.ThreadLogger.Fatal("DispatchPeers里");
                    if (_beforeDispatchPeerList.Count() == 0) //没有可调度的信息
                    {
                        return;
                    }
                    _isDispatchingFlag = true;
                    Dictionary<int, List<IPEndPoint>> blockavailableIPList = new Dictionary<int, List<IPEndPoint>>();
                    //保存每块及对应的可下载的IP列表 
                    Dictionary<string, int> peerAvailableBlocksCountList = new Dictionary<string, int>();
                    //每个ip及其对应可下载的块数
                    Dictionary<string, int> dispatchingQueue = new Dictionary<string, int>(); //正在调度过程的队列，<ip+port,块数>
                    lock (_beforeDispatchListSync)//防止在其他地方修改_beforeDispatchPeerList,否则有可能出错
                    {
                        foreach (KeyValuePair<string, PeerInfo> peer in _beforeDispatchPeerList)
                        {
                            List<int> blockIDList = JobInfo.LocalFileBlocks.GetDownLoadBlockNum(peer.Value.Blocks);
                            peerAvailableBlocksCountList[peer.Key] =
                                JobInfo.LocalFileBlocks.GetDownLoadBlockNum(peer.Value.Blocks).Count;
                            foreach (var blockID in blockIDList)
                            {
                                if (_dowmloadingBlocks != null && _dowmloadingBlocks.Contains(blockID))
                                {
                                    continue;
                                }
                                if (blockavailableIPList != null && !blockavailableIPList.ContainsKey(blockID))
                                {
                                    blockavailableIPList[blockID] = new List<IPEndPoint>();
                                    blockavailableIPList[blockID].Add(peer.Value.IPEndPoint);
                                }
                                else if (blockavailableIPList.ContainsKey(blockID))
                                {
                                    blockavailableIPList[blockID].Add(peer.Value.IPEndPoint);
                                }
                            }
                        }
                    }

                    if (_waitingQueue == null)
                    {
                        _waitingQueue = new Dictionary<int, string>();
                    }
                    _waitingQueue.Clear(); //清空等待下载队列
                    foreach (KeyValuePair<int, List<IPEndPoint>> pair in blockavailableIPList)
                    {

                        if (pair.Value.Count == 1) //只用一个CLient拥有该块
                        {
                            _waitingQueue[pair.Key] = pair.Value[0].ToString();
                            if (dispatchingQueue.ContainsKey(pair.Value[0].ToString()))
                            {
                                dispatchingQueue[pair.Value[0].ToString()]++;
                            }
                            else
                            {
                                dispatchingQueue[pair.Value[0].ToString()] = 1;
                            }

                            continue;
                        }
                        int minCount = int.MaxValue;
                        string ipString = string.Empty;
                        foreach (var ip in pair.Value)
                        {
                            if (dispatchingQueue.ContainsKey(ip.ToString()) && dispatchingQueue[ip.ToString()] < minCount)
                            {
                                minCount = dispatchingQueue[ip.ToString()];
                                ipString = ip.ToString();
                            }
                        }
                        if (ipString != string.Empty)
                        {
                            _waitingQueue[pair.Key] = ipString;
                            if (dispatchingQueue.ContainsKey(ipString))
                            {
                                dispatchingQueue[ipString]++;                                 
                            }
                          
                        }

                    }
                }
                catch (Exception ex)
                {
                    CommonLogger.Logger.Debug("Dispatch 里出问题", ex);
                    
                }


            }
            _isDispatchingFlag = false;

        }

        /// <summary>
        /// 下载分块到本地磁盘
        /// </summary>
        /// <param name="blockId">该分块的序号，以便有序的写入磁盘(范围:1-blockAmount</param>
        /// <param name="blockSize">该分块的大小</param>
        /// <param name="fileName">文件名</param>
        /// <param name="localFilePath">下载方保存下载文件的完全路径</param>
        /// <param name="ipEndPoint">客户端的IP地址</param>
        public void DownloadPeer(int blockId, int blockSize, string localFilePath, IPEndPoint ipEndPoint)
        {
            if (File.Exists(localFilePath) == false) // 2009-09-26,vls,change code to Double-Check Lock Pattern
            {
                lock (_syncRoot)
                {
                    if (File.Exists(localFilePath) == false)
                    {
                        try
                        {
                            //在磁盘上预分配空间
                            using (FileStream fs = new FileStream(localFilePath, FileMode.CreateNew, FileAccess.Write, FileShare.None))
                            {
                                if (JobInfo.FileLen != 0)
                                {
                                    fs.SetLength(JobInfo.FileLen);
                                }
                            }
                        }
                        catch (Exception e)
                        {
                            CommonLogger.Logger.Error("DownloadPeer() 预分配空间: " + e.StackTrace);
                        }
                    }
                }
            }

            int startPos = (blockId - 1) * BasicSetting.BlockSize;
            Stream responseStream = null;
            try
            {
                HttpWebRequest httpWebRequest = (HttpWebRequest)HttpWebRequest.Create("http://" + ipEndPoint.ToString() + "/" + JobInfo.FileName + "|" + JobInfo.Hash + "/" + blockId);
                httpWebRequest.AddRange(startPos, startPos + blockSize - 1);
                httpWebRequest.Method = "GET";
                httpWebRequest.KeepAlive = true;
                HttpWebResponse httpWebResponse = (HttpWebResponse)httpWebRequest.GetResponse();
                responseStream = httpWebResponse.GetResponseStream(); //2009-09-26,vls,应该是拿Response的Stream
                Buffer buffer = JobInfo.Manager.BufferPool.Alloc();
                buffer.StartPos = -2;
                buffer.BlockID = blockId;
                buffer.Hash = JobInfo.Hash;
                buffer.SaveFilePath = localFilePath;
                buffer.IsBufferFinish = false;
                int totalRead = 0;
                int readBytes = 0;
                bool blockDownloadFinishFlag = false;
                do
                {
                    switch (JobInfo.Status)
                    {
                        case JobStatus.Waiting:
                            Thread.Sleep(10000);
                            break;
                        case JobStatus.Downloading:
                            readBytes = responseStream.Read(buffer.Content, totalRead, blockSize - totalRead);
                            totalRead += readBytes;
                            Thread.Sleep(200);


                            if (totalRead == blockSize)//这块下载完成
                            {
                                this.JobInfo.Manager.NotifyPropertyChanged(c => c.DownloadInfos);
                                blockDownloadFinishFlag = true;
                                buffer.StartPos = startPos;
                                buffer.IsBufferFinish = true;
                            }
                            break;
                        case JobStatus.Stop:
                            JobInfo.Manager.BufferPool.Dealloc(buffer);//归还buffer
                            break;
                        default:
                            break;
                    }
                    //停止下载时
                    if (JobInfo.Status == JobStatus.Stop)
                    {
                        lock (_flushToDiskSync)
                        {
                            FlushJobBuffers();
                            lock (_jobThreadCountSync)
                            {
                                _jobThreadCount--;
                                if (_jobThreadCount < 0)
                                {
                                    _jobThreadCount = 0;
                                }
                            }

                            break;//退出while循环                            
                        }

                    }


                    //一块下载完处理
                    if (blockDownloadFinishFlag)
                    {
                        lock (_bufferCurrentCountSync)
                        {
                            _bufferCurrentCount++;
                            blockDownloadFinishFlag = false;
                        }
                        if (_bufferCurrentCount >= _bufferAmount || JobInfo.LocalFileBlocks.IsHaveAllBlocks())//写入磁盘
                        {
                            lock (_flushToDiskSync)
                            {
                                FlushJobBuffers();
                                if (JobInfo.LocalFileBlocks.IsHaveAllBlocks())//如果整个任务已经下载完成
                                {
                                    CommonLogger.Logger.DebugFormat("In DownloadPeer(), 文件:{0} 下载完成", JobInfo.FileName);
                                    this.JobInfo.Manager.NotifyPropertyChanged(c => c.DownloadInfos);
                                    DownLoadEventArgs e = new DownLoadEventArgs(JobStatus.Finish, JobInfo);
                                    JobInfo.Status = JobStatus.Finish;
                                    OnJobFinished(this, e);
                                    lock (JobInfo.Manager.TimerJobList)
                                    {
                                        if (JobInfo.Manager.TimerJobList.ContainsKey(JobInfo.Hash))//取消定时任务
                                        {
                                            JobInfo.Manager.TimerJobList.Remove(JobInfo.Hash);
                                        }
                                    }
                                }
                                lock (_jobThreadCountSync)
                                {
                                    _jobThreadCount--;
                                    if (_jobThreadCount < 0)
                                    {
                                        _jobThreadCount = 0;
                                    }
                                }

                                break;//退出while循环                                   
                            }

                        }
                    }


                }
                while (true);
                CommonLogger.ThreadLogger.DebugFormat("DownloadPeer() Done. BlockID={0}", blockId);
            }
            catch (Exception e)
            {
                CommonLogger.Logger.Error("In DownloadPeer()" + e.StackTrace);
                lock (_ipDisableCountSync)
                {
                    if (_ipDisableCount.ContainsKey(ipEndPoint.ToString()))
                    {
                        _ipDisableCount[ipEndPoint.ToString()]++;
                    }
                    else
                    {
                        _ipDisableCount[ipEndPoint.ToString()] = 1;
                    }

                    if (_ipDisableCount[ipEndPoint.ToString()] >= _jobInfo.Manager.Client.Config.IPRetryCount)//如果大于或等于重连次数
                    {
                        if (_disableIPList != null && _disableIPList.Contains(ipEndPoint.ToString()) == false)
                        {
                            _disableIPList.Add(ipEndPoint.ToString());//增加到过时IP列表
                        }

                    }
                }
                if (_dowmloadingBlocks.Contains(blockId))//失败后，将该块从正在下载的列表中删除
                {
                    _dowmloadingBlocks.Remove(blockId);
                }
                //throw;
            }
            finally
            {
                if (responseStream != null) responseStream.Close();
            }
        }

        /// <summary>
        /// 清空过时的IP列表
        /// </summary>
        public void ClearDisableIPList()
        {
            foreach (string ip in _disableIPList)
            {
                if (_ipDisableCount.ContainsKey(ip))
                {
                    _ipDisableCount.Remove(ip);
                }
            }
            _disableIPList = new List<string>();
        }

        public void FlushJobBuffers()
        {
            List<Buffer> buffers = JobInfo.Manager.BufferPool.GetBufferList(JobInfo.Hash);
            int count;
            if (JobInfo.Status == JobStatus.Stop)
            {
                count = buffers.Count;
            }
            else
            {
                count = _bufferAmount;
            }
            foreach (var b in buffers)
            {
                if (count <= 0)
                {
                    break;

                }
                if (b.IsBufferFinish && WriteToDisk(b))//写入成功
                {

                    JobInfo.LocalFileBlocks.Set(b.BlockID, true);//更新自己的BitArray
                    if (_dowmloadingBlocks != null && _dowmloadingBlocks.Contains(b.BlockID))//写入磁盘后，将对应的块号从正在下载列表中删除
                    {
                        _dowmloadingBlocks.Remove(b.BlockID);
                    }
                    CommonLogger.ThreadLogger.Fatal("资源名 " + _jobInfo.FileName + "写入成功！块号： " + b.BlockID + "  写完后_bufferCurrentCount为: " + _bufferCurrentCount);

                }
                JobInfo.Manager.BufferPool.Dealloc(b);//回收buffer到bufferPool
                lock (_bufferCurrentCountSync)
                {
                    _bufferCurrentCount--;
                }
                count--;

            }

        }

        public virtual void OnJobFinished(object sender, DownLoadEventArgs e)
        {
            if (JobStatusChanged != null)
            {
                JobStatusChanged(sender, e);
            }
        }

        /// <summary>
        /// 将下载的分块写入磁盘
        /// </summary>
        /// <param name="buffer">存储已经下载的buffer</param>
        /// <return>返回是否写入成功（true为成功，false为失败）</return>
        public bool WriteToDisk(Buffer buffer)
        {
            if (buffer.StartPos < 0)
            {
                return false;
            }
            try
            {
                using (FileStream fileStream = new FileStream(buffer.SaveFilePath, FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.ReadWrite))
                {
                    int blockSize;
                    if (JobInfo.Manager.HashJobInfoDict.ContainsKey(buffer.Hash) && JobInfo.Manager.HashJobInfoDict[buffer.Hash].BlockAmount == buffer.BlockID)//如果是最后一块
                    {
                        blockSize = JobInfo.Manager.HashJobInfoDict[buffer.Hash].LastBlockLen;
                    }
                    else
                    {
                        blockSize = BasicSetting.BlockSize;
                    }
                    fileStream.Position = buffer.StartPos;
                    fileStream.Write(buffer.Content, 0, blockSize);
                    fileStream.Flush();
                    fileStream.Close();
                }

            }
            catch (Exception e)
            {
                CommonLogger.Logger.Error("WriteToDisk() " + e.StackTrace);
                return false;
            }

            return true;
        }

        /// <summary>
        /// 暂停下载
        /// </summary>
        /// <returns>返回一个bool值标识是否暂停成功</returns>
        public bool PauseDownload()
        {
            JobInfo.Status = JobStatus.Waiting;
            return true;
        }

        /// <summary>
        /// 停止下载
        /// </summary>
        /// <returns>返回一个bool值标识是否停止成功</returns>
        public bool StopDownload()
        {
            JobInfo.Status = JobStatus.Stop;
            if (JobInfo.Manager.TimerJobList.ContainsKey(JobInfo.Hash))//取消定时任务
            {
                JobInfo.Manager.TimerJobList.Remove(JobInfo.Hash);
            }
            return true;
        }

        /// <summary>
        /// 开始下载
        /// </summary>
        /// <returns>返回一个bool值标识是否开始成功</returns>
        public bool StartDownload()
        {
            _otherWorkThreadPool.QueueWorkItem(new Action(DownloadMain));
            lock (JobInfo.Manager.TimerJobList)
            {
                if (JobInfo.Manager.TimerJobList.ContainsKey(JobInfo.Hash) == false)
                {
                    JobInfo.Manager.TimerJobList[JobInfo.Hash] = new TimerJob(GetPeerList, ClearDisableIPList);
                }
            }
            JobInfo.Status = JobStatus.Downloading;
            _isResumeFromDisk = false;
            if (JobInfo.Manager.Client.Config.ServerIP != null)
            {
                GetPeerList(JobInfo.Manager.Client.Config.ServerIP);
            }

            return true;
        }

        /// <summary>
        /// 下载的主要控制函数
        /// </summary>
        public void DownloadMain()
        {
            bool isExitDownload = false;
            while (true)
            {
                
                switch(JobInfo.Status)
                {
                    case JobStatus.Init:
                        break;
                    case JobStatus.Downloading:
                        lock (_dispatchSync)
                        {
                            if (_isDispatchingFlag == false && _waitingQueue != null && _waitingQueue.Count > 0 && _jobThreadCount < JobInfo.Manager.Client.Config.JobThreadLimit)
                            {
                                int blockLen;
                                int blockID;
                                IPEndPoint ipEndPoint;
                                if (_waitingQueue.First().Key == JobInfo.BlockAmount)
                                {
                                    blockLen = JobInfo.LastBlockLen;

                                }
                                else
                                {
                                    blockLen = BasicSetting.BlockSize;
                                }

                                string ipAddress = _waitingQueue.First().Value;
                                IPAddress ipAddr = IPAddress.Parse(ipAddress.Split(':')[0]);
                                ipEndPoint = new IPEndPoint(ipAddr, int.Parse(ipAddress.Split(':')[1]));
                                blockID = _waitingQueue.First().Key;
                                _downloadThreadPool.QueueWorkItem(new Action<int, int, string, IPEndPoint>(DownloadPeer),
                                                                  blockID, blockLen, JobInfo.LocalFilePath.GetStringWithLastSlash() + JobInfo.FileName, ipEndPoint);// 2009.09.19 vls, Passs full path (with filename) into DownloadPeer() instead of path only.

                                _waitingQueue.Remove(_waitingQueue.First().Key);//从等待队列中去掉
                                if (_dowmloadingBlocks == null)
                                {
                                    _dowmloadingBlocks = new List<int>();
                                }
                                _dowmloadingBlocks.Add(blockID);
                                if (_downloadingQueue.ContainsKey(ipEndPoint.ToString()))
                                {
                                    _downloadingQueue[ipEndPoint.ToString()]++;
                                }
                                else
                                {
                                    _downloadingQueue[ipEndPoint.ToString()] = 1;
                                }
                                _jobThreadCount++;
                            }
                            break;
                        }

                    case JobStatus.Waiting:
                        break;
                    case JobStatus.Finish:
                        isExitDownload = true;
                        break;
                    case JobStatus.Stop:
                        isExitDownload = true;
                        break;
                    default:
                        break;

                }
                if (isExitDownload)
                {
                    break;
                }   
                Thread.Sleep(200);
            }
            CommonLogger.ThreadLogger.Debug("退出 Download Main.....................................");

        }

        /// <summary>
        /// 恢复下载
        /// </summary>
        /// <returns>返回一个bool值标识是否恢复成功</returns>
        public bool ResumeDownload()
        {
            if (JobInfo.Status == JobStatus.Stop && _isResumeFromDisk == true)//如果不是从暂停下载的状态中恢复
            {
                StartDownload();
            }

            JobInfo.Status = JobStatus.Downloading;
            return true;
        }

    }
}
